/*
 * chat_hash.h
 *
 *  Created on: 2012-6-30
 *      Author: rendong
 */

#ifndef CHAT_HASH_H_
#define CHAT_HASH_H_

#include "chat_log.h"

// hash 节点
typedef struct _chat_hash_table_item_s chat_hash_table_item_t;

struct _chat_hash_table_item_s
{
	char *key;
	void *value;

	size_t hash;

	chat_hash_table_item_t *next;
};

// hash table 结构
typedef struct _chat_hash_table_s
{
	chat_hash_table_item_t ** items;
	size_t nlimit;
	size_t size;
} chat_hash_table_t;

/**
 * 初始化hash table
 */
void chat_hash_init(chat_hash_table_t * hashtable, size_t capacity);

/**
 * 向hash表中加入数据
 * @return 键存在，返回1， 否则返回0
 */
int chat_hash_put(chat_hash_table_t * hashtable, char *key, void *value);

/**
 * 获取数据
 */
void* chat_hash_get(chat_hash_table_t * hashtable, char *key);

/**
 * 删除
 */
void chat_hash_del(chat_hash_table_t * hashtable, char *key);

/**
 * hash 33 算法 来自php代码
 */
static inline unsigned long chat_inline_hash_func(const char *key, size_t nkey)
{
	register unsigned long hash = 5381;

	/* variant with the hash unrolled eight times */
	for (; nkey >= 8; nkey -= 8) {
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
	}

	switch (nkey) {
		case 7: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 6: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 5: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 4: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 3: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 2: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 1: hash = ((hash << 5) + hash) + *key++; break;
		case 0: break;
	}

	return hash;
}


#endif /* CHAT_HASH_H_ */
